﻿using System;
using System.Collections.Generic;
using System.Linq;
using KC.Framework.Extension;
using KC.Model.Account;
using KC.Framework.Base;
using KC.Framework.Tenant;
using KC.Service.Account.AutoMapper.Converter;
using KC.DTO.Account;
using KC.DTO.Core;

namespace KC.Service.Account.AutoMapper.Profile
{
    public class AccountMapperProfile : global::AutoMapper.Profile
    {
        public AccountMapperProfile()
        {
            CreateMap<Entity, EntityDTO>();
            CreateMap<EntityDTO, Entity>();

            CreateMap<ProcessLogBase, ProcessLogBaseDTO>()
                .ForMember(target => target.TypeName, config => config.Ignore());
            CreateMap<ProcessLogBaseDTO, ProcessLogBase>();

            CreateMap<TreeNode<Organization>, TreeNodeDTO<OrganizationDTO>>()
                .IncludeBase<Entity, EntityDTO>();
            CreateMap<TreeNodeDTO<OrganizationDTO>, TreeNode<Organization>>()
                .IncludeBase<EntityDTO, Entity>();

            #region 组织架构、角色及用户
            CreateMap<Role, RoleDTO>()
                .ForMember(target => target.@checked, config => config.Ignore())
                .ConvertUsing<RoleDTOConverter>();
            CreateMap<RoleDTO, Role>()
                .ConvertUsing<RoleConverter>();

            CreateMap<Organization, OrganizationDTO>()
                .IncludeBase<TreeNode<Organization>, TreeNodeDTO<OrganizationDTO>>()
                .ForMember(target => target.id, config => config.MapFrom(src => src.Id))
                .ForMember(target => target.text, config => config.MapFrom(src => src.Name))
                .ForMember(target => target.ParentName, config => config.MapFrom(src => src.ParentNode.Name))
                .ForMember(target => target.children, config => config.MapFrom(src => src.ChildNodes))
                .ForMember(target => target.UserNamesInfo,
                    config => 
                        config.MapFrom(
                            src => string.Join("; ", src.Users.Select(m => m.DisplayName))))
                .ForMember(target => target.@checked, config => config.Ignore())
                .ForMember(target => target.Users, config => config.Ignore())
                //.ForMember(target => target.OrganizationDisplayListId, config => config.Ignore())
                //.ForMember(target => target.OrganizationDisplayListName, config => config.Ignore())
                .ForMember(target => target.CreatedByAndName, config => config.Ignore());

            CreateMap<OrganizationDTO, Organization>()
                .IncludeBase<TreeNodeDTO<OrganizationDTO>, TreeNode<Organization>>()
                .ForMember(target => target.Id, config => config.MapFrom(src => src.id))
                .ForMember(target => target.Name, config => config.MapFrom(src => src.text))
                .ForMember(target => target.ChildNodes, config => config.Ignore())
                .ForMember(target => target.ParentNode, config => config.Ignore())
                .ForMember(target => target.OrganizationUsers, config => config.Ignore());

            CreateMap<UserTracingLog, UserTracingLogDTO>();
            CreateMap<UserTracingLogDTO, UserTracingLog>()
                .ForMember(target => target.User, config => config.Ignore());

            CreateMap<User, UserDTO>()
                .ForMember(target => target.UserId, config => config.MapFrom(src => src.Id))
                .ForMember(target => target.PositionLevelName,
                    config => config.MapFrom(src => src.PositionLevel.ToDescription()))
                .ForMember(target => target.Organizations, config => config.MapFrom(src => src.Organizations))
                .ForMember(target => target.OrganizationIds,
                    config =>
                        config.MapFrom(
                            src =>
                                src.UserOrganizations.Any()
                                    ? src.UserOrganizations.Select(m => m.OrganizationId).ToList()
                                    : default(List<int>)))
                .ForMember(target => target.OrganizationName,
                    config =>
                        config.MapFrom(
                            src =>
                                src.UserOrganizations.Any()
                                    ? src.UserOrganizations.Select(m => m.Organization).ToCommaSeparatedStringByFilter(m => m.Name)
                                    : string.Empty))
                .ForMember(target => target.RoleIds,
                    config => 
                        config.MapFrom(
                            src =>
                                src.UserRoles.Any()
                                    ? src.UserRoles.Select(idntityRole => idntityRole.RoleId)
                                    : new List<string>()))
                .ForMember(target => target.RoleNames,
                    config =>
                        config.MapFrom(
                            src =>
                                src.UserRoles.Any()
                                    ? src.UserRoles.Select(m => m.Role.DisplayName).ToList()
                                    : new List<string>()))
                .ForMember(target => target.IsSystemAdmin,
                    config =>
                        config.MapFrom(
                            src => src.Id.Equals(RoleConstants.AdminUserId, StringComparison.OrdinalIgnoreCase)))
                .ForMember(target => target.IsEditMode, config => config.Ignore())
                .ForMember(target => target.TenantName, config => config.Ignore())
                .ForMember(target => target.TenantNickName, config => config.Ignore())
                .ForMember(target => target.id, config => config.MapFrom(src => src.Id))
                .ForMember(target => target.Password, config => config.Ignore());
            CreateMap<UserDTO, User>()
                .ForMember(target => target.Id, config => config.MapFrom(src => src.UserId))
                .ForMember(target => target.UserRoles, 
                    config => 
                        config.MapFrom(
                            src =>
                                src.RoleIds.Any()
                                    ? src.RoleIds.Select(roleId => new UsersInRoles() { RoleId = roleId, UserId = src.UserId })
                                    : new List<UsersInRoles>()))
                .ForMember(target => target.UserOrganizations,
                    config =>
                        config.MapFrom(
                            src =>
                                src.OrganizationIds.Any()
                                    ? src.OrganizationIds.Select(orgId => new UsersInOrganizations() { OrganizationId = orgId, UserId = src.UserId })
                                    : new List<UsersInOrganizations>()))
                .ForMember(target => target.PasswordHash, config => config.Ignore())
                .ForMember(target => target.Roles, config => config.Ignore())
                .ForMember(target => target.Organizations, config => config.Ignore())
                .ForMember(target => target.Claims, config => config.Ignore())
                .ForMember(target => target.UserTracingLogs, config => config.Ignore())
                .ForMember(target => target.Recommended, config => config.Ignore())
                .ForMember(target => target.UserOrganizations, config => config.Ignore());

            //CreateMap<User, UserInfoDTO>()
            //    .ForMember(target => target.UserId, config => config.MapFrom(src => src.Id))
            //    .ForMember(target => target.PositionLevelName, config => config.MapFrom(src => src.PositionLevel.ToDescription()))
            //    .ForMember(target => target.OrganizationIds, 
            //        config => config.MapFrom(
            //            src => 
            //                src.UserOrganizations != null && src.UserOrganizations.Any()
            //                    ? src.UserOrganizations.Select(m => m.OrganizationId) 
            //                    : default(List<int>)))
            //    .ForMember(target => target.OrganizationName, config => config.MapFrom(src => src.UserOrganizations.FirstOrDefault() != null ? src.UserOrganizations.FirstOrDefault().Organization.Name : string.Empty))
            //    .ForMember(target => target.RoleIds, config => config.MapFrom(src => src.UserRoles.Select(idntityRole => idntityRole.RoleId)))
            //    .ForMember(target => target.IsSystemAdmin, config => config.MapFrom(src => src.Id.Equals(RoleConstants.AdminUserId, StringComparison.OrdinalIgnoreCase)))
            //    .ForMember(target => target.RoleNames, config => config.Ignore())
            //    .ForMember(target => target.IsEditMode, config => config.Ignore())
            //    .ForMember(target => target.TenantName, config => config.Ignore())
            //    .ForMember(target => target.id, config => config.MapFrom(src => src.Id))
            //    .ForMember(target => target.Password, config => config.Ignore());
            //CreateMap<UserInfoDTO, User>()
            //    .ForMember(target => target.Id, config => config.MapFrom(src => src.UserId))
            //    .ForMember(target => target.UserRoles, config => config.MapFrom(src => src.RoleIds.Select(roleId => new UsersInRoles() { RoleId = roleId, UserId = src.UserId })))
            //    .ForMember(target => target.PasswordHash, config => config.Ignore())
            //    //.ForMember(target => target.Claims, config => config.Ignore())
            //    //.ForMember(target => target.Logins, config => config.Ignore())
            //    .ForMember(target => target.Recommended, config => config.Ignore())
            //    .ForMember(target => target.UserOrganizations, config => config.Ignore());

            CreateMap<User, UserSimpleDTO>()
                .ForMember(target => target.id, config => config.MapFrom(src => src.Id))
                .ForMember(target => target.UserId, config => config.MapFrom(src => src.Id))
                .ForMember(target => target.PositionLevelName, config => config.MapFrom(src => src.PositionLevel.ToDescription()))
                .ForMember(target => target.UserOrgIds,
                    config =>
                        config.MapFrom(
                            src =>
                                src.UserOrganizations.Any()
                                    ? src.UserOrganizations.Select(m => m.OrganizationId).ToList()
                                    : default(List<int>)))
                .ForMember(target => target.UserOrgNames,
                    config =>
                        config.MapFrom(
                            src =>
                                src.UserOrganizations.Any()
                                    ? src.Organizations.Select(m => m.Name).ToList()
                                    : default(List<string>)))
                .ForMember(target => target.UserRoleIds,
                    config =>
                        config.MapFrom(
                            src =>
                                src.UserRoles.Any()
                                    ? src.UserRoles.Select(m => m.RoleId).ToList()
                                    : default(List<string>)))
                .ForMember(target => target.UserRoleNames,
                    config =>
                        config.MapFrom(
                            src =>
                                src.UserRoles.Any()
                                    ? src.Roles.Select(m => m.DisplayName).ToList()
                                    : default(List<string>)))
                .ForMember(target => target.TenantName, config => config.Ignore());
            #endregion
        }
    }
}
